/**
 * tftp.h
 * TFTP Managing library.
 * By Group 1
 */
#ifndef TFTP_H_INCLUDED
#define TFTP_H_INCLUDED

#include <string>
#include "polonet.h"
using namespace std;

#define CONNECTION_PORT 8080 //TFTP Default
#define SLEEP_MS 10 //Sleep time in MS
#define SLEEP (SLEEP_MS*1000)

#define MAX_STR_LENGTH 256
#define BUFFER_SIZE 2048 // Do not make it any smaller. This is to ensure that all packets can be read with a single call of readbuffer.

#define RRQ     0x0001
#define WRQ     0x0002
#define DATA    0x0003
#define ACK     0x0004
#define ERROR   0x0005
#define ECHO    0x0006 // Custom defined command ECHO. When this packet is sent, the system returns the same packet with the same content.
#define DIE     0x0007 // Custom defined command DIE, to turn the server remotely off.
/*
ECHO Packet
2by: Opcode
str: String
1by: \0
*/

#define ERROR_UNDEFINED             0x0000
#define ERROR_FILENOTFOUND          0x0001
#define ERROR_ACCESSVIOLATION       0x0002
#define ERROR_DISKFULL              0x0003
#define ERROR_ILLEGALOPERATION      0x0004
#define ERROR_UNKNOWNTRANSFERID     0x0005
#define ERROR_FILEALREADYEXISTS     0x0006
#define ERROR_NOSUCHUSER            0x0007

typedef struct
{
    unsigned char MSB;
    unsigned char LSB;
} BigEndianShort;

BigEndianShort getBigEndianFromNumber(short number);
short readBigEndian(BigEndianShort BEShort);

bool connectToServer(PolonetConn &conn, const char* hostAddress);
void disconnectFromServer(PolonetConn &conn);
int loadBuffer(PolonetConn &conn, char *buffer, int buffersize);
void transmitECHOPacket(PolonetConn &conn, const char* message);
void transmitRRQPacket(PolonetConn &conn, const char* filename);
void transmitWRQPacket(PolonetConn &conn, const char* filename);
void transmitACKPacket(PolonetConn &conn, short blockNumber);
void transmitDATAPacket(PolonetConn &conn, short blockNumber, char* data, const int dataSize);
void transmitERRORPacket(PolonetConn &conn, short errorNumber,const char* errmsg);
void transmitDIEPacket(PolonetConn &conn);

short getPacketType(char* packet);
bool readRRQWRQPacket(char* &filename, char* &mode, char* packet);
bool readECHOPacket(char* &message, char* packet);
bool readDATAPacket(char* data, short &blockNumber, char* packet,const int packetsize);
bool readERRORPacket(char* &errmsg,short &errorNumber, char* packet);
bool readACKPacket(short &blockNumber, char* packet);



#endif // TFTP_H_INCLUDED
